//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.
// 

package peermaliziosi;


simple Peer
{
    parameters:
        @signal[newSeeder](type="int");
        @statistic[numSeeder](title="Number of Seeders"; source="newSeeder"; record=vector,stats; interpolationmode=none);
        
        @signal[newDownloader](type="int");
        @statistic[numDownloader](title="Number of Downloaders"; source="newDownloader"; record=vector,stats; interpolationmode=none);
        
        @signal[seederTime](type="simtime_t");
        @statistic[seederTime](title="Tempo per diventare seeder"; source="seederTime"; record=stats; interpolationmode=none);
        
        @signal[blocksSent](type="float");
        @statistic[blocksSent](title="Percentuale di condivisione = # blocchi inviati / # blocchi del file"; source="blocksSent"; record=vector,stats; interpolationmode=none);
        
        @signal[fileCompletation](type="float");
        @statistic[fileCompletation](title="Percentuale di completamento del file"; source="fileCompletation"; record=vector,stats; interpolationmode=none);

        @signal[duplicatedBlocks](type="int");
        @statistic[duplicatedBlocks](title="Numero di blocchi duplicati ricevuti"; source="duplicatedBlocks"; record=vector,stats; interpolationmode=none);

        @signal[effectiveCancels](type="int");
        @statistic[effectiveCancels](title="Numero di Cancel che hanno effettivamente cancellato una richiesta pendente"; source="effectiveCancels"; record=vector,stats; interpolationmode=none);
        
		@signal[numRequestSent](type="int");
        @statistic[numRequestSent](title="Numero di messaggi Request inviati"; source="numRequestSent"; record=vector,stats; interpolationmode=none);    
        
        @signal[numPieceSent](type="int");
        @statistic[numPieceSent](title="Numero di messaggi Piece inviati"; source="numPieceSent"; record=vector,stats; interpolationmode=none);
        
        @signal[numCancelSent](type="int");
        @statistic[numCancelSent](title="Numero di messaggi Cancel inviati"; source="numCancelSent"; record=vector,stats; interpolationmode=none);
        
        @signal[numRequestForMe](type="int");
        @statistic[numRequestForMe](title="Numero di messaggi Request ricevuti"; source="numRequestForMe"; record=vector,stats; interpolationmode=none);    
        
        @signal[numPieceForMe](type="int");
        @statistic[numPieceForMe](title="Numero di messaggi Piece ricevuti"; source="numPieceForMe"; record=vector,stats; interpolationmode=none);
        
        @signal[numCancelForMe](type="int");
        @statistic[numCancelForMe](title="Numero di messaggi Cancel ricevuti"; source="numCancelForMe"; record=vector,stats; interpolationmode=none);
            
        
        @display("i=block/routing,yellow");
        bool endGameEnabled = default(false);
        //effettua unchoking anche in base al numero di Cancel inviati ad un peer remoto
        bool unchokeWithCancelNum = default(false);
        // numero di pezzi da scaricare nella fase random prima di passare a rarest first
        int randomPhaseLength = default(4);
  		// massimo numero di blocchi richiesti allo stesso peer remoto in una sola volta
        int maxBlockRequestNum = default(5);
        // numero massimo di peer ai quali invio dati contemporaneamente
        int max_uploads= default(4);
  		// numero minimo di unchoked peer che veranno ottenuti mediante optimistic unchoking
        int min_uploads = default(2);
        
        // ritardo in attesa di unirsi allo swarm
    	volatile double joinDelay @unit(s) = default( exponential(5min) );
    	// probabilita' che si unisca inizialmente con torrent vuoto oppureuno inizializzato a random
    	double initJoinEmptyRandom = default(0.5);
    	// probabilita' che si unisca con torrent vuoto
    	double joinEmpty = default(0.5);
    	// probabilita' che si unisca con lo stesso torrent interrotto oppure con uno inizializzato a random
    	double joinAgainRandom = default(0.7);
    	// ritardo dopo il quale il peer esce dallo swarm. "0" indica che non uscira' mai
    	volatile double leaveDelay @unit(s) = default(truncnormal(3h, 1h));
        // probabilita' che un pezzo sia posseduto (usato per inizializzare BitTorrentFile)
        double piecesInit = default(0.5);
    	
    	// tempo di servizio per l'estrazione dalla coda in ingresso
    	// simula il tempo di servizio necessario per processare i pacchetti in ingresso
    	volatile double incomingServingTime @unit(s) = default(truncnormal(0.4s,0.2s)); 
        
        // soglia minima di peer conosciuti, se si e' sotto questa soglia bisogna fare una nuova "tracker request" per ottenere altri peer
        int minPeerSet = default(30);
        // massimo numero di peer remoti connessi per un singolo torrent (e quindi anche il massimo numero di peer restituiti dal tracker)
        int maxPeerSet = default(55);
        // true per disabilitare l'invio dei KeepAlive
        bool disableKeepAlive = default(false);
        // la selezione del prossimo pezzo da scaricare viene fatta fra gli ultimi N in modo casuale
        int randomPieceSelectionSize = default(5);
        
    gates:
        inout io;
}
